package com.drm.netschool.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.drm.common.util.AliPayPram;
import com.drm.common.util.ConfigUtil;
import com.drm.common.util.DateUtil;
import com.drm.common.util.EncryptTool;
import com.drm.common.util.IdCreater;
import com.drm.common.util.JsonMapper;
import com.drm.common.util.NumberUtil;
import com.drm.common.util.PaymentType;
import com.drm.common.util.PriceUtils;
import com.drm.common.util.StringUtil;
import com.drm.netschool.entity.DrmBuyCourse;
import com.drm.netschool.entity.DrmBuyCourseExample;
import com.drm.netschool.entity.DrmBuyOrder;
import com.drm.netschool.entity.DrmBuyOrderDetail;
import com.drm.netschool.entity.DrmBuyOrderExample;
import com.drm.netschool.entity.DrmPayTrace;
import com.drm.netschool.entity.DrmSalesPromotion;
import com.drm.netschool.entity.DrmStudyCoin;
import com.drm.netschool.entity.DrmUser;
import com.drm.netschool.entity.DrmUserSinfo;
import com.drm.netschool.entity.extend.AddStudyCourseDTO;
import com.drm.netschool.entity.extend.CartInfo;
import com.drm.netschool.mapper.DrmBuyCourseMapper;
import com.drm.netschool.mapper.DrmBuyOrderDetailMapper;
import com.drm.netschool.mapper.DrmBuyOrderMapper;
import com.drm.netschool.mapper.DrmPayTraceMapper;
import com.drm.netschool.mapper.DrmUserMapper;
import com.drm.netschool.mapper.manual.DrmBuyCartExtendMapper;
import com.drm.netschool.redis.RedisUtil;

@Service
public class OrderService {

	static String _NOTIFY_URL = "_NOTIFY_URL";
	static String _RETURN_URL = "_RETURN_URL";
	
	String  DRM_STUDYCOURSE_NOTIFY_REDIS_QUEUE_NAME = "DRM:STUDYCOURSE_NOTIFY_QUEUE";

	private Logger LOGGER = LoggerFactory.getLogger(OrderService.class);

	@Autowired
	private DrmBuyOrderMapper orderMapper;

	@Autowired
	private DrmBuyOrderDetailMapper orderDetailMapper;

	@Autowired
	private DrmPayTraceMapper drmPayTraceMapper;

	@Autowired
	private DrmBuyOrderDetailMapper drmBuyOrderDetailMapper;

	@Autowired
	private DrmBuyCourseMapper drmBuyCourseMapper;

	@Autowired
	private DrmBuyCartExtendMapper cartExtendMapper;

	@Autowired
	private DrmUserMapper userMapper;

	@Autowired
	private RedisUtil redisUtil;
	
	@Autowired
	private DrmStudyCoinService studyCoinService;
	
	@Autowired
	private DrmUserSinfoService userInfoService;

	public DrmBuyOrder getById(String id) {
		return orderMapper.selectByPrimaryKey(id);
	}
	
	public DrmBuyCourse getByUserIdAndCourseId(Long userId, Long courseId){
		DrmBuyCourseExample example = new DrmBuyCourseExample();
		example.createCriteria().andUserIdEqualTo(userId).andCourseIdEqualTo(courseId).andComfirmYnEqualTo(1);
		List<DrmBuyCourse> list = drmBuyCourseMapper.selectByExample(example);
		return list == null || list.isEmpty() ? null : list.get(0);
	}

	public int addOrder(DrmBuyOrder entity) {
		if (entity == null) {
			return 0;
		}
		entity.setCreateDt(DateUtil.current());
		entity.setCommitDt(DateUtil.current());
		entity.setConfirmDt(DateUtil.current());
		entity.setOrderSt(1);
		return orderMapper.insert(entity);
	}

	public int updateOrder(String orderId, Integer orderState) {
		if (StringUtil.empty(orderId)) {
			return 0;
		}
		DrmBuyOrder entity = orderMapper.selectByPrimaryKey(orderId);
		if (entity == null) {
			throw new RuntimeException("订单不存在");
		}
		entity.setOrderSt(orderState);
		entity.setPayComfirm(DateUtil.current());
		return orderMapper.updateByPrimaryKey(entity);
	}

	public DrmBuyOrder addOrder(Long userId, List<CartInfo> cartList, DrmSalesPromotion promotion, DrmUserSinfo us, boolean useState) {
		Long count = getCount(cartList); // 订单金额
		Integer discountAmount = getDiscountAmount(promotion, count).intValue(); // 活动优惠金额
		Integer total = count.intValue() - discountAmount;
		// 学习币使用数量(单位： 分)
		Integer corn = 0;
		Integer userCorn = 0;
		if (useState) {
			DrmStudyCoin studyCoin = studyCoinService.getDrmStudyCoin();
			Long coinAmount =  getCoin2Fen(studyCoin, us);
			if(total - coinAmount.intValue() > 0){
				corn = coinAmount.intValue();
			}else{
				corn = total;
			}
			userCorn = getFen2Coin(corn, studyCoin);
		}
		Integer payAmount = total - corn;
		DrmBuyOrder order = new DrmBuyOrder();
		
		if (payAmount == 0) {// 学习币直接支付成功
			order.setOrderSt(4);
			order.setPayTp(4);
			order.setPayComfirm(DateUtil.current());
		} else {// 待其他方式支付
			order.setOrderSt(1);
		}
		
		String orderId = IdCreater.getId().toString();
		order.setOrderId(orderId);
		order.setUserId(userId);
		order.setCreateDt(DateUtil.current());
		order.setCommitDt(DateUtil.current());
		order.setConfirmDt(DateUtil.current());
		order.setPayPrice(payAmount);
		order.setPayCorn(userCorn);
		order.setPayDiscount(discountAmount);
		orderMapper.insert(order);

		// 点单支付轨迹
		DrmPayTrace payTrace = new DrmPayTrace();
		payTrace.setComfrinYn(0);// 未确认
		payTrace.setConfrimDesc(null);
		payTrace.setConfrimUid(userId);
		payTrace.setId(IdCreater.getId());
		payTrace.setOrderId(orderId);
		payTrace.setPayDt(DateUtil.current());
		payTrace.setPayPrice(count);
		payTrace.setPayState(0);// 生成订单
		payTrace.setPayTp(null);// 后补上
		payTrace.setPayUserid(userId);
		drmPayTraceMapper.insertSelective(payTrace);
		List<Long> cartIds = new ArrayList<Long>();
		for (CartInfo cart : cartList) {
			cartIds.add(cart.getCartId());
			// 新增订单明细表记录
			DrmBuyOrderDetail orderDtl = new DrmBuyOrderDetail();
			orderDtl.setOrderId(order.getOrderId());
			orderDtl.setCourseId(cart.getCourseId());
			orderDtl.setCreateDt(DateUtil.current());
			orderDtl.setCartId(cart.getCartId());
			drmBuyOrderDetailMapper.insertSelective(orderDtl);

			// 新增购买课程表记录
			DrmBuyCourse buyCourse = new DrmBuyCourse();
			buyCourse.setCourseId(cart.getCourseId());
			buyCourse.setUserId(userId);
			buyCourse.setBuyDt(DateUtil.current());
			// buyCourse.setOrderPrice(new Double(order.getPayPrice() * 100).longValue());
			buyCourse.setOrgPrice(cart.getOrgPrice());
			buyCourse.setCurrentPrice(cart.getCurPrice());
			buyCourse.setOrderId(order.getOrderId());
			buyCourse.setComfirmYn(order.getOrderSt() == 4 ? 1 : 0);// 直接确认或待确认
			drmBuyCourseMapper.insertSelective(buyCourse);
			
			if(order.getOrderSt() == 4 && order.getPayTp() == 4){
				AddStudyCourseDTO d = new AddStudyCourseDTO();
				d.setCourseId(cart.getCourseId());
				d.setUserId(cart.getUserId());
				d.setDesc("");
				redisUtil.listPushHead(DRM_STUDYCOURSE_NOTIFY_REDIS_QUEUE_NAME, JsonMapper.toJson(d));
			}
		}
		
		if(order.getOrderSt() == 4 && order.getPayTp() == 4){
			us.setUserLearncredit(us.getUserLearncredit() - userCorn);
			userInfoService.update(us);
		}
			
		// 更新购物车状态
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("state", 3);
		param.put("userId", userId);
		param.put("cartIds", cartIds);
		cartExtendMapper.updateCartState(param);
		return order;
	}

	public String comfirmPay(DrmBuyOrder order, PaymentType type) {
		// 需要保持在 DrmPaySetting 表中使用更好
		String notifyUrl = ConfigUtil.getString(type.name() + _NOTIFY_URL);
		String returnUrl = ConfigUtil.getString(type.name() + _RETURN_URL);

		String orderid = order.getOrderId();
		String token = DigestUtils.md5Hex(orderid + DateUtil.dateToStr(DateUtil.current(), DateUtil.FORMAT_DEFAULT_MIN));
		String mainkey = null;
		try {
			mainkey = EncryptTool.sha1HEX(orderid + token);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// pay_tp 支付类型 1：支付宝 2：财付通 3：银联
		Map<String, String> allmap = new HashMap<String, String>();
		String orderContent = "{}";
		String payType = "";

		if (type.equals(PaymentType.ALIPAY)) {
			orderContent = this.createAliPay(order, notifyUrl, returnUrl);
			payType = "1";
		}

		if (!StringUtil.empty(payType)) {
			// 更新订单 // 支付类型，1支付宝，2财付通，3网银 更新 支付类型
			updateOrderPayType(order.getOrderId(), NumberUtil.parseInteger(payType));
		}

		allmap.put("orderContent", orderContent);
		allmap.put("payType", payType);
		redisUtil.hashMultipleSet(mainkey, allmap, 3600);

		String REDIRICT_PAY_URL = ConfigUtil.getString("REDIRICT_PAY_URL");
		return REDIRICT_PAY_URL + "" + orderid + "/" + token;
	}

	public void updateOrderPayType(String orderId, int payType) {
		DrmBuyOrder order = orderMapper.selectByPrimaryKey(orderId);
		if (order == null)
			return;

		order.setPayTp(payType);
		DrmBuyOrderExample example = new DrmBuyOrderExample();
		example.createCriteria().andOrderIdEqualTo(orderId);
		orderMapper.updateByExample(order, example);
	}

	/********************** private ***********************/
	private Long getDiscountAmount(DrmSalesPromotion promotion, Long count) {
		if (promotion == null) {
			return 0L;
		}

		if (promotion.getPromotionTp() == 1) {
			if (count > promotion.getPromotionMoney()) {
				return promotion.getReduceMoney();
			}
		} else if (promotion.getPromotionTp() == 2) {
			if (count > promotion.getPromotionMoney()) {
				return count * promotion.getReduceMoney();
			}
		}
		return 0L;
	}

	private Long getCount(List<CartInfo> cartList) {
		Long count = 0L;
		if (cartList != null) {
			for (CartInfo cart : cartList) {
				count += cart.getCurPrice();
			}
		}
		return count;
	}
	
	public Long getCoin2Fen(DrmStudyCoin studyCoin, DrmUserSinfo userInfo){
		if(studyCoin == null || NumberUtil.parseInteger(studyCoin.getScoinCnt()) == 0){
			return 0L;
		}
		if(userInfo == null || NumberUtil.parseInteger(userInfo.getUserLearncredit()) == 0){
			return 0L;
		}
		Integer total = userInfo.getUserLearncredit() * (NumberUtil.parseInteger(studyCoin.getRmbCnt()) * 100)/NumberUtil.parseInteger(studyCoin.getScoinCnt());
		return Long.valueOf(total.toString());
	}
	
	public Integer getFen2Coin(Integer amount, DrmStudyCoin studyCoin){
		if(studyCoin == null){
			return 0;
		}
		
		return amount * studyCoin.getScoinCnt()/(studyCoin.getRmbCnt() * 100);
	}

	private String createAliPay(DrmBuyOrder order, String notifyUrl, String returnUrl) {
		DrmUser user = userMapper.selectByPrimaryKey(order.getUserId());
		AliPayPram vo = new AliPayPram();
		// 订单表述
		vo.body = order.getRemarkDesc();
		// 客户端IP
		vo.exter_invoke_ip = "";
		vo.notify_url = notifyUrl;
		// 商户订单号
		vo.out_trade_no = order.getOrderId();
		// 商家好吗
		vo.partner = "";
		vo.return_url = returnUrl;
		vo.subject = "账号:" + user.getUserLnm() + ",购买课程订单支付,金额:" + PriceUtils.CoinToYuan(order.getPayPrice()) + "元";
		// 支付总额 元
		vo.total_fee = PriceUtils.CoinToYuan(order.getPayPrice());
		// 支付类型
		vo.payment_type = "1";
		vo.anti_phishing_key = "";
		return JsonMapper.toJson(vo);
	}
}
